package cuckoo.log.impl.std;

import java.io.PrintWriter;
import java.io.StringWriter;

import cuckoo.log.Logger;
import cuckoo.log.util.MessageFormatter;
import cuckoo.util.DateUtils;

public class StdLoggerImpl implements Logger {

	private static final String LINE = System.getProperty("line.separator");

	private static final String LOG_FORMAT = "%s - [%s] - %s - %s";

	private enum Level {
		DEBUG,
		INFO,
		WARN,
		ERROR
	}

	private String loggerName;

	public StdLoggerImpl(String loggerName) {
		this.loggerName = loggerName;
	}

	@Override
	public void debug(String msg) {
		format(Level.DEBUG, msg);
	}

	@Override
	public void debug(String msg, Throwable e) {
		format(Level.DEBUG, msg + LINE + transform(e));
	}

	@Override
	public void debug(String msg, Object... args) {
		format(Level.DEBUG, MessageFormatter.arrayFormat(msg, args).getMessage());
	}

	@Override
	public void info(String msg) {
		format(Level.INFO, msg);
	}

	@Override
	public void info(String msg, Throwable e) {
		format(Level.INFO, msg + LINE + transform(e));
	}

	@Override
	public void info(String msg, Object... args) {
		format(Level.INFO, MessageFormatter.arrayFormat(msg, args).getMessage());
	}

	@Override
	public void warn(String msg) {
		format(Level.WARN, msg);
	}

	@Override
	public void warn(String msg, Throwable e) {
		format(Level.WARN, msg + LINE + transform(e));
	}

	@Override
	public void warn(String msg, Object... args) {
		format(Level.WARN, MessageFormatter.arrayFormat(msg, args).getMessage());
	}

	@Override
	public void error(String msg) {
		format(Level.ERROR, msg);
	}

	@Override
	public void error(String msg, Throwable e) {
		format(Level.ERROR, msg + LINE + transform(e));
	}

	@Override
	public void error(String msg, Object... args) {
		format(Level.ERROR, MessageFormatter.arrayFormat(msg, args).getMessage());
	}

	private void format(Level level, String msg) {
		String currtime = DateUtils.date2Str(DateUtils.datetimeFormat_milli);
		System.out.println(String.format(LOG_FORMAT, currtime, level.toString(), loggerName, msg));
	}

	private String transform(Throwable t) {
		StringWriter sw = new StringWriter();
		PrintWriter pw = new PrintWriter(sw);
		t.printStackTrace(pw);
		return sw.getBuffer().toString();
	}
}
